#include"udp_client.hpp"

static void usage(string proc)
{
    cout<<"Usage:\n\t"<< proc <<" port\n"<<endl;
}

void *Revcfrom(void * args)
{
    int sock=*(static_cast<int*>(args));
    while(true)
    {
        char buf[1024];
        struct sockaddr_in cur;
        socklen_t len =sizeof(cur);
        int n=recvfrom(sock,buf,strlen(buf)-1,0,(struct sockaddr*)&cur,&len);
        
        if(n>0)
        {
            buf[n]='\0';
            cout<<buf<<endl;
        }


    }
        

}




//./udp_client ip  port
int main(int argc ,char * argv[])
{
    if(argc!=3)
    {
        usage(argv[0]);
        exit(USING_ERR);
    }
    string serverip=argv[1];  
    uint16_t serverport =atoi(argv[2]);

    int sock=socket(AF_INET,SOCK_DGRAM,0);
    if(sock<0)
    {
        cerr<<"创建 socker 失败: "<<strerror(errno)<<endl;
        exit(SOCKER_ERR);
    }
    //2.
    //2.1client 要绑定，但是不需要自己绑定  通信本质[client:client_port,server:server_port];
    //2.2都用一个端口的话会导致第二个进程启动不了
    //2.3让系统分配，防止启动冲突
    //2.4服务器的端口不能随便改变，需要同一规范化

    //明确 serverip serverport
    struct sockaddr_in server;
    memset(&server,0,sizeof(server));
    server.sin_family=AF_INET;//ip4
    server.sin_port=htons(serverport);//主机转网络
    server.sin_addr.s_addr=inet_addr(serverip.c_str()); //字符转点分10进制

    pthread_t _tid;
    pthread_create(&_tid,nullptr,Revcfrom,&sock);//把sock传进去
  
    while(true)
    {
        //发
        string message;
        cout<<"[client]# ";
        getline(cin,message);
        //什么时候绑定？取决什么时候调用系统调用，操作系统会绑定（在第一次调用时，绑定随机端口）

        sendto(sock,message.c_str(),message.size(),0,(struct sockaddr*)&server,sizeof(server));
    }

    


    return 0;
}